extends Node2D

#方向信号
signal position_changed(pos:Vector2)

# 位置和尺寸
const BOX_SCALE = 0.16666667 #映射框相对于屏幕的缩放比例
var box = Rect2(0,0,0,0)
var indicator_radius=0 # 指示点半径
var indicator_center: Vector2 = Vector2.ZERO #指示点中心 
var screen_size = Vector2.ZERO # 屏幕尺寸

# 状态
var is_box_active = false #是否激活


func _ready():
	#根据屏幕尺寸初始化映射框和指示点尺寸
	screen_size = get_viewport().size
	box.size.x = screen_size.x*BOX_SCALE
	box.size.y = screen_size.y*BOX_SCALE
	indicator_radius = max(box.size.x, box.size.y)/6


func _input(event):
	if event is InputEventScreenTouch or event is InputEventMouseButton:
		if event.pressed:
			# 当屏幕被点击时，激活
			is_box_active = true
			var sword_pos = get_parent().get_node("Sword").position #获取剑的位置
			var indicator_relative_x = sword_pos.x / screen_size.x * box.size.x # 指示点在映射框中的相对x
			var indicator_relative_y = sword_pos.y / screen_size.y * box.size.y # 指示点在映射框中的相对y
			box.position = event.position - Vector2(indicator_relative_x,indicator_relative_y)  #确定位置
			indicator_center = event.position
		else:
			# 当手指离开屏幕时，隐藏
			is_box_active = false
			emit_signal("position_changed",Vector2(-1,-1)) 
	elif event is InputEventScreenDrag or event is InputEventMouseMotion:
		# 确定指示点中心
		if not box.has_point(event.position) :
			indicator_center = get_intersection_point(box, event.position)
		else:
			indicator_center = event.position

func _physics_process(delta):
	if is_box_active:
		#发送位置信号
		var pos = (indicator_center-box.position)/BOX_SCALE # 指示点映射到屏幕的目标位置
		emit_signal("position_changed",pos)
	queue_redraw()

#绘制映射框
func _draw():
	if is_box_active:
		draw_rect(box,Color.AQUA)
		draw_circle(indicator_center,indicator_radius,Color.CHARTREUSE)
		
		
# 获取线段（rect.center~point）与矩形rect的交点
func get_intersection_point(rect: Rect2, point: Vector2) -> Vector2:
	var rect_center = rect.position + rect.size / 2
	var direction = (point - rect_center).normalized()
	
	# 定义射线的起点和终点
	var ray_start = rect_center
	var ray_end = rect_center + direction * 1e6  # 足够大的值
	
	# 定义矩形的四条边
	var edges = [
		# 上边
		[Vector2(rect.position.x, rect.position.y + rect.size.y), Vector2(rect.position.x + rect.size.x, rect.position.y + rect.size.y)],
		# 下边
		[Vector2(rect.position.x, rect.position.y), Vector2(rect.position.x + rect.size.x, rect.position.y)],
		# 左边
		[Vector2(rect.position.x, rect.position.y), Vector2(rect.position.x, rect.position.y + rect.size.y)],
		# 右边
		[Vector2(rect.position.x + rect.size.x, rect.position.y), Vector2(rect.position.x + rect.size.x, rect.position.y + rect.size.y)]
	]
	
	var closest_intersection = Vector2(-1,-1)
	var min_distance = INF
	
	for edge in edges:
		var intersection = line_segment_intersection(ray_start, ray_end, edge[0], edge[1])#计算两条边交点
		if intersection != Vector2(-1,-1):#有交点
			#选择离矩形中心点最近的交点
			var distance = intersection.distance_to(ray_start)
			if distance < min_distance:
				min_distance = distance
				closest_intersection = intersection
	
	return closest_intersection 

#获取两条线段的交点
func line_segment_intersection(p1: Vector2, p2: Vector2, p3: Vector2, p4: Vector2) -> Vector2:
	var denom = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)
	if denom == 0:
		return Vector2(-1,-1)  # 平行或共线，返回一个不可能的值，表示null
	
	var ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denom
	var ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denom
	
	if ua >= 0 and ua <= 1 and ub >= 0:
		return p1 + (p2 - p1) * ua
	else:
		return Vector2(-1,-1)
